#include "NetDefs.h"
#include "SyncWrapper.h"
#include <time.h>
#include <windows.h>
void SyncWrapper::CarEnteredUpperCam(int car_id)
{
	UppercamV.insert(pair<int,ExtendedCar>(car_id,ExtendedCar())); 
	UppercamV[car_id].car_id = car_id;
	//time_t rawtime;
	//time (&rawtime );
	//UppercamV[car_id].entry_time=rawtime;
	UppercamV[car_id].ii=ind;
	//cout << UppercamV[car_id].ii;
	ind++;
	SyncAndUpdate();
}
void SyncWrapper::CarEnteredGroundCam(int LP)
{
	GroundcamV.insert(pair<int,ExtendedCar>(LP,ExtendedCar())); 
	GroundcamV[LP].license_plate  = LP;
	//time_t rawtime;
	//time (&rawtime );
	//GroundcamV[LP].entry_time=rawtime;
	GroundcamV[LP].ii=ind;
	//cout << GroundcamV[LP].ii;
	ind++;
	SyncAndUpdate();
}

void SyncWrapper::CarExits(int car_id) 
{
	for each (pair<int,ExtendedCar> p in UppercamV)
	{
		if(p.first==car_id)
		{
			UppercamV[car_id].car_parking =-2;
			return;
		}
	}
	ParkinglotDB::instance().CarExits(car_id);
}
bool SyncWrapper::CarParked(int car_id, int x, int y)
{
	for each (pair<int,ExtendedCar> p in UppercamV)
	{
		if(p.first==car_id)
		{
			UppercamV[car_id].x=x;
			UppercamV[car_id].y=y;
			return true;
		}
	}
	return ParkinglotDB::instance().CarParked(car_id,x,y);
}

int SyncWrapper::CarUnparked(int x, int y)
{
	int a=ParkinglotDB::instance().isThisParkingSlot(x,y);
	if(a==-1)
		return -1;
	for each (pair<int,ExtendedCar> p in UppercamV)
	{
		if(ParkinglotDB::instance().isThisParkingSlot(p.second.x,p.second.y)==a)
		{
			UppercamV[p.first].x=-10;
			UppercamV[p.first].y=-10;
			return p.first;
		}
	}
	return ParkinglotDB::instance().CarUnparked(x,y);
}

void SyncWrapper::addVideo( int carId, string video){
	ParkinglotDB::instance().addVideo(carId,video);
	return;
}


void SyncWrapper::SyncAndUpdate()
{
	if(UppercamV.size()==0 || GroundcamV.size()==0)
		return;
	ExtendedCar uCar,gCar;
	uCar.ii=ind+1;
	gCar.ii=ind+1;
	int uc,gc;	
	for each (pair<int,ExtendedCar> tmp in UppercamV)
		if(uCar.ii>tmp.second.ii)
		{
			uc=tmp.first;
			uCar=tmp.second;
		}

	for each (pair<int,ExtendedCar> tmp in GroundcamV)
		if(gCar.ii>tmp.second.ii)
		{
			gc=tmp.first;
			gCar=tmp.second;
		}

	ParkinglotDB::instance().CarEntered(uCar.car_id);
	ParkinglotDB::instance().SetLicensePlate(uCar.car_id,gCar.license_plate);
	if(uCar.x!=-10)
		ParkinglotDB::instance().CarParked(uCar.car_id,uCar.x,uCar.y);
	if(uCar.car_parking==-2)
		ParkinglotDB::instance().CarExits(uCar.car_id);

	UppercamV.erase(uc);
	GroundcamV.erase(gc);
	return;
}

string SyncWrapper::getLastExitVideo( int carId ){
	return ParkinglotDB::instance().getCarVideo(carId);	
}


void SyncWrapper::getCarInfo( int carId , Socket* sock ){
	char output_char[50];
	string output = "";
	ParkinglotDB::instance().IsEligible(carId,output);				/*7Returns true if the car is aligable to enter the lot*/ 
	sock->SendLine(output);
	output = "";
	ParkinglotDB::instance().WhenEntered(carId,output);			/*12 rerurns the time in which the car entered to the parking lot*/ 
	sock->SendLine(output);
	output = "";
	int location = ParkinglotDB::instance().GetLocation(carId);
	if( location == -1 ) output = "car driving in parking lot";
	else if( location == -2 ) output = "car not in parking lot";
	else{ 
		sprintf(output_char, "car in parking spot #%d" , location );
		output = output_char;
	}
	sock->SendLine(output);
	output = "";
	ParkinglotDB::instance().HowLongCarIn(carId,output);			/*3States how long was the car in the lot*/
	sock->SendLine(output);
	output = "";
	ParkinglotDB::instance().NumOfTimes(carId,output);			/*6Returns the number of times the car entered to the parking lot*/ 
	sock->SendLine(output);
	output = "";
	output = "Last Exit Video: " + getLastExitVideo( carId );
	sock->SendLine(output);
	return;
}


void SyncWrapper::getParkingLotInfo( Socket* sock ){
	string output = "";
	ParkinglotDB::instance().HowManySlotsFree(output);							/*2States how many parking slots are free*/
	sock->SendLine(output);
	output = "";
	ParkinglotDB::instance().HowManyEntered(output);						/*5Returns the number of cars that entered to the parking lot*/
	sock->SendLine(output);
	output = "";
	ParkinglotDB::instance().HowManySlotsTaken(output);
	sock->SendLine(output);
	output = "";
	ParkinglotDB::instance().TheMostWantedSlot(output);						/*4Returns the most wanted slot in the prking lot*/ 
	sock->SendLine(output);
	return;
}


